package com.cac.demo.util;

import cn.hutool.core.util.XmlUtil;
import com.cac.demo.newCode.cemop.dto.MomAssAOTaskDTO;
import com.cac.demo.newCode.cemop.dto.MomAssWorkPackagePlanDTO;
import com.cac.demo.newCode.cemop.dto.RootDTO;
import org.w3c.dom.*;

import java.io.InputStream;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @className: XmlReadUtil
 * @description: （描述这个类的作用）
 * @author:
 * @date: 2024/6/22 14:31:31 周六
 * @version: 1.0
 */
public class XmlReadUtil {

    // XML文档对象
    private Document doc;

    // XML文档元素节点的根节点对象
    private Element rootElement;

    /**
     * @Title: XmlReadUtil
     * @Description: 参数构造，通过XML文件输入流构造XML文档对象与文档元素根节点对象
     * @param: in XML文件输入流
     */
    public XmlReadUtil(InputStream in) {
        this.doc = XmlUtil.readXML(in);
        this.rootElement = XmlUtil.getRootElement(doc);
    }


    /**
     * @param tagName 指定的元素节点名
     * @return ArrayList<Map < String, String>>
     * @Title: getAttributesByTagName
     * @Description: 获取xml文件指定元素节点的属性值，因为可能存在多个同名元素节点，所以返回List
     */
    public ArrayList<Map<String, String>> getAttributesByTagName(String tagName) {
        // 方法返回的List
        ArrayList<Map<String, String>> attributesList = new ArrayList<>();

        // 获取所有指定的元素节点
        NodeList nodeList = this.rootElement.getElementsByTagName(tagName);

        // 遍历元素节点，将属性值转为Map
        for (int i = 0; i < nodeList.getLength(); i++) {

            NamedNodeMap nodeMap = nodeList.item(i).getAttributes();

            Map<String, String> AttributesMap = new HashMap<>();

            for (int j = 0; j < nodeMap.getLength(); j++) {
                String key = nodeMap.item(j).getNodeName();
                String value = nodeMap.item(j).getNodeValue();

                AttributesMap.put(key, value);
            }

            attributesList.add(AttributesMap);
        }

        return attributesList;
    }

    /**
     * @param parentNodeNameArray     父节点名称数组，示例：new String[] {"AIKDocument","AIKsequence"}
     * @param parentAttributeKeyArray 父节点属性参数数组，示例：new String[] {"aoType","sequenceNum"}
     * @param tagName                 指定的元素节点名
     * @return ArrayList<Map < String, String>>
     * @Title: getAttributesByTagName
     * @Description: 获取xml文件指定元素节点的属性值，并将指定父节点的指定属性一并添加到节点里
     */
    public ArrayList<Map<String, String>> getAttributesByTagName(String[] parentNodeNameArray, String[] parentAttributeKeyArray, String tagName) {
        // 方法返回的List
        ArrayList<Map<String, String>> attributesList = new ArrayList<>();

        // 获取所有指定的元素节点
        NodeList nodeList = this.rootElement.getElementsByTagName(tagName);

        // 遍历元素节点，将属性值转为Map，同时将父节点的属性值加入
        for (int i = 0; i < nodeList.getLength(); i++) {

            // 获取当前元素节点的属性值
            Map<String, String> AttributesMap = new HashMap<>();

            Node node = nodeList.item(i);
            NamedNodeMap nodeMap = node.getAttributes();
            for (int j = 0; j < nodeMap.getLength(); j++) {
                String key = nodeMap.item(j).getNodeName();
                String value = nodeMap.item(j).getNodeValue();

                AttributesMap.put(key, value);
            }

            // 将父节点的属性值加入
            for (String parentNodeName : parentNodeNameArray) {

                Node parentNode = node.getParentNode();

                // 循环遍历，找到当前节点的父节点
                while (!parentNodeName.equals(parentNode.getNodeName())) {

                    parentNode = parentNode.getParentNode();

                }

                // 找到父节点后，将父节点的属性值加入
                for (String parentAttribute : parentAttributeKeyArray) {

                    NamedNodeMap parentNodeMap = parentNode.getAttributes();

                    for (int j = 0; j < parentNodeMap.getLength(); j++) {

                        String key = parentNodeMap.item(j).getNodeName();

                        if (key.equals(parentAttribute)) {

                            String value = parentNodeMap.item(j).getNodeValue();

                            AttributesMap.put(key, value);
                        }
                    }
                }
            }

            attributesList.add(AttributesMap);
        }

        return attributesList;
    }

    public  void mapToDTO(Map<String, String> map, Object dto) {
        List<SimpleDateFormat> dateFormats = new ArrayList<>();
        dateFormats.add(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        dateFormats.add(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"));
        dateFormats.add(new SimpleDateFormat("yyyy-MM-dd")); // 添加多种格式
        dateFormats.add(new SimpleDateFormat("yyyy/MM/dd"));



        for (Map.Entry<String, String> entry : map.entrySet()) {
            try {
//                Field field = dto.getClass().getDeclaredField(entry.getKey());
                // 检查dto类中是否包含该字段
                Field field = null;
                try {
                    field = dto.getClass().getDeclaredField(entry.getKey());
                } catch (NoSuchFieldException e) {
                    // 如果没有找到字段，跳过当前循环
                    continue;
                }
                field.setAccessible(true);
                // 检查字段是否为Date类型
                if (field.getType().equals(Date.class)) {
                    Date date = parseDate((String) entry.getValue(), dateFormats);

                    field.set(dto, date);
                }
                else if (field.getType().equals(BigDecimal.class)) {
                    field.set(dto, entry.getValue().isEmpty()?0:new BigDecimal(entry.getValue()));
                }
                else if (field.getType().equals(int.class)) {
                    field.set(dto, entry.getValue().isEmpty()?0:Integer.parseInt(entry.getValue()));
                }
                else if (field.getType().equals(Double.class)) {
                    field.set(dto, entry.getValue().isEmpty()?0:Double.parseDouble(entry.getValue()));
                } else if (field.getType().equals(Float.class)) {
                    field.set(dto, entry.getValue().isEmpty()?0:Float.parseFloat(entry.getValue()));
                } else if (field.getType().equals(Integer.class)) {
                    field.set(dto, entry.getValue().isEmpty()?0:Integer.parseInt(entry.getValue()));
                }else {
                    if ( entry.getValue().isEmpty())
                    {
                        field.set(dto, null);
                    }
                    else{
                        field.set(dto, entry.getValue()); // 直接赋值非Date类型
                    }
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }

    // 尝试多种格式解析日期
    private static Date parseDate(String dateString, List<SimpleDateFormat> dateFormats) {
        for (SimpleDateFormat format : dateFormats) {
            try {
                return format.parse(dateString);
            } catch (ParseException ignored) {
            }
        }
        System.err.println("Unparseable date: " + dateString);
        return new Date(); // 返回null或其他默认值
    }
}
